package com.googlecode.sparda.commons.io.stream.policy;

import java.io.OutputStream;
import java.util.concurrent.LinkedBlockingDeque;

import com.googlecode.sparda.commons.io.stream.ManagedOutputStream;

/**
 * An {@link AbstractCMOSPolicy} is a skeleton class to build a closing managed output stream policy
 * based on open stream.
 * @author Fabio Grucci (<i>alias</i> <b>Phoenix</b>)
 *
 */
public abstract class AbstractCMOSPolicy implements ClosingManagedOutputStreamPolicy {
	/**
	 * The stream currently opened.
	 */
	protected final LinkedBlockingDeque<ManagedOutputStream<? extends OutputStream>> openedStream;
	/**
	 * Build an {@link AbstractCMOSPolicy} that store the currently opened stream.
	 */
	public AbstractCMOSPolicy() {
		this.openedStream = new LinkedBlockingDeque<ManagedOutputStream<? extends OutputStream>>();
	}
	/*
	 * (non-Javadoc)
	 * @see com.googlecode.sparda.commons.io.stream.policy.ClosingManagedOutputStreamPolicy#notifyDefinitelyClosed(com.googlecode.sparda.commons.io.stream.ManagedOutputStream)
	 */
	@Override
	public void notifyDefinitelyClosed(ManagedOutputStream<? extends OutputStream> closedStream) {
		this.openedStream.remove(closedStream);
	}
	/*
	 * (non-Javadoc)
	 * @see com.googlecode.sparda.commons.io.stream.policy.ClosingManagedOutputStreamPolicy#notifyNewManagedOutputStream(com.googlecode.sparda.commons.io.stream.ManagedOutputStream)
	 */
	@Override
	public void notifyNewManagedOutputStream(ManagedOutputStream<? extends OutputStream> newStream) {
		this.notifyOpen(newStream);
	}
	/*
	 * (non-Javadoc)
	 * @see com.googlecode.sparda.commons.io.stream.policy.ClosingManagedOutputStreamPolicy#notifyOpen(com.googlecode.sparda.commons.io.stream.ManagedOutputStream)
	 */
	@Override
	public void notifyOpen(ManagedOutputStream<? extends OutputStream> openedStream) {
		this.openedStream.add(openedStream);
	}
	/*
	 * (non-Javadoc)
	 * @see com.googlecode.sparda.commons.io.stream.policy.ClosingManagedOutputStreamPolicy#notifyTemporaryClosed(com.googlecode.sparda.commons.io.stream.ManagedOutputStream)
	 */
	@Override
	public void notifyTemporaryClosed(ManagedOutputStream<? extends OutputStream> temporaryClosedStream) {
		this.openedStream.remove(temporaryClosedStream);
	}

}
